/**
 *
 */
package fr.ece.ing4.chatapplication.client;

import java.util.ArrayList;
import java.util.List;

import org.jgroups.Address;
import org.jgroups.Message;
import org.jgroups.View;

import fr.ece.ing4.chatapplication.api.ChatMessage;
import fr.ece.ing4.chatapplication.api.TransportDriver;
import fr.ece.ing4.chatapplication.api.TransportReceiver;

/**
 * @author enzo
 *
 */
public class ClientController implements TransportReceiver{

    private final String controlCluster = "ControlCluster";

    private String clientName;
    private TransportDriver driver;
    private ChatRoomController chatRoom1, chatRoom2, chatRoom3;
    private List<String> chatroomAvailable;

    private Address address;
    private Address serverAddress;

    private ClientFrame clientFrame;

    public void init() {

        clientFrame = new ClientFrame(this);
        driver = new TransportDriver(controlCluster, clientName, this);
        address = driver.getAddress();
        chatroomAvailable = new ArrayList<String>();
        connect();
    }


    public ClientController() {

        new PopupFrame("Choose Username", "Enter an unique username", this);

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ClientController();

    }

    @Override
    public void printView(View v) {
        // TODO Auto-generated method stub

    }

    @Override
    public void receiveChatMessage(Message msg) {
        // TODO Auto-generated method stub

        ChatMessage m = (ChatMessage) msg.getObject();
        String[] dataTab;
        //if the msg is a request it is none of our business as a client
        if(m.getType() != ChatMessage.REQUEST)
        {
            System.out.println(m.getType() + m.getData());
            switch(m.getFlag())
            {
                //if the server ACK connection, we save its address
                case ChatMessage.CONNECT : serverAddress=m.getSource();
                    break;
                //if the server ACK chatroom creation, we join the chatroom
                case ChatMessage.CREA : joinChatRoom(m.getData());
                    break;
                // if the server has kicked us, we leave the network
                // print a message on view
                case ChatMessage.KICK : if(m.getData().isEmpty()) shutdown();
                    // si kick d'un channel ( lors du delete) print message on view
                else leaveChatRoom(m.getData());
                    break;
                // if the server shutdown, we leave the network
                case ChatMessage.LEAVE: shutdown();
                    // print a message on view !!

                    break;
                //if the server send  a notif regarding chatrooms
                case ChatMessage.CHATROOMS: dataTab = m.getData().split("-");
                    // on récupère toutes les chatrooms
                    clientFrame.deleteAllChatFromList();
                    for( int i = 0;i<dataTab.length;i++) {
                        chatroomAvailable.add(dataTab[i]);
                        clientFrame.addChatroomToList(dataTab[i]);
                    }
                    //on les passe à la vue


                    break;
                //si server passe info sur users d'une chatroom
                case ChatMessage.USERS: dataTab=m.getData().split("-");
                    // on récupère le nom de la chatroom
                    String chatroom=dataTab[0];
                    if(dataTab.length>1)
                    { // on recupère les noms des users de la chatroom
                        List<String> users= new ArrayList<String>();
                        for(int i=1;i<dataTab.length;i++)
                        {
                            users.add(dataTab[i]);
                        }
                    }
                    // on passe à la vue
                    break;
            }
        }
    }

    //connecting to the network 
    public void connect()
    {
        ChatMessage msg = new  ChatMessage(address,serverAddress, controlCluster, ChatMessage.REQUEST, ChatMessage.CONNECT, null);
        driver.sendMessage(msg);
    }

    //asking for available chatrooms
    public void getChatRoomsAvailable()
    {
        ChatMessage msg = new ChatMessage(address,serverAddress,controlCluster,ChatMessage.REQUEST,ChatMessage.CHATROOMS,null);
        driver.sendMessage(msg);
    }

    //joining a chatroom
    public void joinChatRoom(String chatRoomName)
    {
        if(chatRoom1!=null && chatRoom2 != null && chatRoom3 != null)
        {
            // déjà rejoint 3 chatroom impossible d'en rejoindre une de plus
            new PopupFrame("ERROR !", "Already joined 3 chatrooms !", this);
        }
        else if(chatRoom1==null) {
            chatRoom1 = new ChatRoomController(chatRoomName,clientName,serverAddress, clientFrame, 1);
            driver.sendMessage(new ChatMessage(address,serverAddress,controlCluster,ChatMessage.REQUEST,ChatMessage.JOIN,chatRoomName));
            clientFrame.changeTitleTab(chatRoomName, 1 );
        }
        else if(chatRoom2==null) {
            chatRoom2 = new ChatRoomController(chatRoomName,clientName,serverAddress,clientFrame, 2);
            driver.sendMessage(new ChatMessage(address,serverAddress,controlCluster,ChatMessage.REQUEST,ChatMessage.JOIN,chatRoomName));
            clientFrame.changeTitleTab(chatRoomName, 2 );
        }
        else if(chatRoom3==null) {
            chatRoom3 = new ChatRoomController(chatRoomName,clientName,serverAddress,clientFrame, 3);
            driver.sendMessage(new ChatMessage(address,serverAddress,controlCluster,ChatMessage.REQUEST,ChatMessage.JOIN,chatRoomName));
            clientFrame.changeTitleTab(chatRoomName, 3 );
        }

    }

    //asking for a chatroom creation
    public void createChatRoom(String name)
    {
        ChatMessage m = new ChatMessage(address,serverAddress,controlCluster,ChatMessage.REQUEST,ChatMessage.CREA,name);
        driver.sendMessage(m);
        clientFrame.addChatroomToList(name);
    }

    //leaving a chatroom
    public void leaveChatRoom(String name)
    {
        ChatMessage m = new ChatMessage(address,serverAddress,controlCluster,ChatMessage.NOTIF,ChatMessage.LEAVE,name);
        driver.sendMessage(m);
        if(chatRoom1.getChatRoomName().equals(name))
        {
            chatRoom1.disconnect();
            chatRoom1=null;
        }
        else if(chatRoom2.getChatRoomName().equals(name))
        {
            chatRoom2.disconnect();
            chatRoom2=null;
        }
        else if(chatRoom3.getChatRoomName().equals(name))
        {
            chatRoom3.disconnect();
            chatRoom3=null;
        }

    }

    //send a message on the network
    public void sendMessage(String chatRoom, String message)
    {
        ChatMessage msg = new ChatMessage(address,null,chatRoom,ChatMessage.CHAT,ChatMessage.CHAT,message);
        driver.sendMessage(msg);
    }

    /**
     * @return the clientName
     */
    public String getClientName() {
        return clientName;
    }

    /**
     * @param clientName the clientName to set
     */
    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    /**
     * @return the clientFrame
     */
    public ClientFrame getClientFrame() {
        return clientFrame;
    }
    //leaving the network

    public void shutdown()
    {
        driver.disconnect();
        if(chatRoom1!=null) chatRoom1.disconnect();
        if(chatRoom2!=null) chatRoom2.disconnect();
        if(chatRoom3!=null) chatRoom3.disconnect();

    }


    @Override
    public void onViewChanged(View v) {
        // TODO Auto-generated method stub

    }

}
